package com.server;

import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

public class UserPackageFilter {
	private Map<Integer, Integer>	prefs;
	private final int				DEFAULT_PREF	= 0xFFFFFFFF;

	/**
	 * Creates a package filter, that contains informations about which clients that accepts which package types.
	 */
	public UserPackageFilter()
	{
		prefs = new HashMap<Integer, Integer>();
	}

	/**
	 * Register a client, initiated with preference: <code>0xFFFFFFFF</code> (allow all).
	 * 
	 * @param clientId
	 *            The id of the client which is to be registered.
	 */
	public void registerClient(int clientId)
	{
		prefs.put(clientId, DEFAULT_PREF);
	}

	/**
	 * Return the preferences for the <code>clientId</code> provided.
	 * 
	 * @param clientId
	 *            the client for which preferences is to be returned
	 * @return the preferences for client <code>clientId</code>
	 */
	public int getPrefs(int clientId)
	{
		if (prefs.get(clientId) == null)
		{
			throw new NoSuchElementException("Prefs for client: " + clientId + " doesnt exist.");
		}
		return prefs.get(clientId);
	}

	/**
	 * Returns whether or not a package of <code>type</code> is allowed to be passed client <code>clientId</code>
	 * 
	 * @param clientId
	 *            the id of the client which is to be checked
	 * @param type
	 *            the type of the packaged which is to be checked
	 * @return true of a package of <code>type</code> is accepted by <code>clientId</code>
	 */
	public boolean passFilter(int clientId, int type)
	{
		if (prefs.get(clientId) == null)
		{
			throw new NoSuchElementException("Prefs for client: " + clientId + " doesnt exist.");
		}
		return (prefs.get(clientId) & type) != 0;
	}

	/**
	 * Unsubscribe of for a certain kind of packages for a specific client.
	 * 
	 * @param clientId
	 *            the id of the client who is about to unsubscribe
	 * @param type
	 *            the type of the package for which a client is unsubscribing for
	 */
	public void unsubscribe(int clientId, int type)
	{
		if (prefs.get(clientId) == null)
		{
			throw new NoSuchElementException("Prefs for client: " + clientId + " doesnt exist.");
		}
		prefs.put(clientId, prefs.get(clientId) & ~type);
	}

	/**
	 * Subscribe for a certain kind of package for a specific client.
	 * 
	 * @param clientId
	 *            the id of the client who is about to subscribe
	 * @param type
	 *            the type of the package for which a client is subscribing to
	 */
	public void subscribe(int clientId, int type)
	{
		if (prefs.get(clientId) == null)
		{
			throw new NoSuchElementException("Prefs for client: " + clientId + " doesnt exist.");
		}
		prefs.put(clientId, prefs.get(clientId) | type);
	}

}
